//
// Singleton.hpp for  in ~/Dropbox/Projets/raytracer-2016/Includes/DesignPattern/Singleton/
//
// Made by Jonathan
// Login   <ledey_l@epitech.net>
//
// Started on  Fri Sep 20 22:55:37 2013 Jonathan
// Last update Fri Sep 20 23:22:32 2013 Jonathan
//

#ifndef			SINGLETON_HPP_
# define		SINGLETON_HPP_

# include		<cstdlib>

# include		"DesignPattern/ThreadPool/Mutex.hpp"

namespace		DesignPattern
{
  namespace		Singleton
  {
    template <class Type>
    class		Singleton
    {
    protected:
      static Type	*mInstance;
      static DesignPattern::ThreadPool::Mutex	*mMutex;

    private:
      static void	DestroyInstance(void)
      {
	if (mInstance != NULL)
	  {
	    delete mInstance;
	    mInstance = NULL;
	  }
      }

    public:
      Singleton(void)
      {
	return;
      }

      virtual ~Singleton(void)
      {
	if (mMutex != NULL)
	  {
	    delete mMutex;
	    mMutex = NULL;
	  }
      }

      static Type	*GetInstance(void)
      {
	if (mInstance == NULL)
	  {
	    mMutex->Lock();
	    if (mInstance == NULL)
	      {
		mInstance = new Type();
		std::atexit(DestroyInstance);
	      }
	    mMutex->Unlock();
	  }
	return (mInstance);
      }
    };

    template <class Type>
    Type		*Singleton<Type>::mInstance = NULL;

    template <class Type>
    DesignPattern::ThreadPool::Mutex	*Singleton<Type>::mMutex =
      new DesignPattern::ThreadPool::Mutex;
  };
};

#endif			/* SINGLETON_HPP_ */
